import logging
import sys
import serial
import re
import time
import pandas as pd
import os
import threading
from logger import MyLogging
import argparse

# AT_COM_PORT = 'COM6'

# 设置串口参数
# ser = serial.Serial(AT_COM_PORT, 9600, 8, "N", 1, 2)  # 替换为你的串口号和波特率
# ser = Nonejppip
global rsrp_timeout
rsrp_timeout = 0
global reboot_timer_start
reboot_timer_start = time.time()
global reboot_timer_start_now
reboot_timer_start_now = time.time()

class SharedValue:
    def __init__(self, value=None):
        self.lock = threading.Lock()
        self.value = value

cereg_value = SharedValue(None)  # 创建一个可在线程间共享的整数值（模拟）

def read_cereg_thread(serial_port, cereg_value):
    try:
        while True:
            with cereg_value.lock:
                cereg_value.value = get_cereg_value(serial_port)
                if cereg_value.value is not None:
                    print(f"cereg_value:{cereg_value.value}")
            time.sleep(1)  # 每隔10秒读取一次CEREG值（根据实际需求调整频率）
    except Exception as e:
        # print(f"read_cereg_thread: {e}")
        logger.info(f"read_cereg_thread: {e}")

def read_rsrp(serial_port):
    try:
        while True:
            serial_port.write(b'AT+NUESTATS\r\n')
            # print("send AT+NUESTATS success")
            logger.info("send AT+NUESTATS success")
            response_lines = []
            while True:  # 循环读取，直到找到“OK”为止
                line = serial_port.readline().decode('utf-8').strip()
                response_lines.append(line)
                
                if line == 'OK':
                    break

            for line in response_lines:
                if line.startswith("Signal power:"):
                    pattern = r'Signal power:\s*(-?\d+)'
                    match = re.search(pattern, line)
                    if match:
                        rsrp = int(match.group(1)) / 10.0
                        if -150 <= rsrp <= 0:
                            global rsrp_timeout
                            rsrp_timeout = rsrp_timeout + 1
                            if rsrp_timeout >= 50:
                                rsrp_timeout = 0
                                return "err"
                            return rsrp
                        else:
                            # print(f"RSRP ({rsrp}) is not in the required range (-150 to -120). Retrying after 5 seconds...")
                            logger.info(f"RSRP ({rsrp}) is not in the required range (-150 to -120). Retrying after 5 seconds...")
                            
                            time.sleep(2)
                            break
            else:
                # print("Failed to parse RSRP from the response. Retrying after 5 seconds...")
                logger.info("Failed to parse RSRP from the response. Retrying after 5 seconds...")
            
            time.sleep(2)
    except Exception as e:
        # print(f"read_rsrp: {e}")
        logger.info(f"read_rsrp: {e}")
    

def get_cereg_value(serial_port):
    # 发送AT+CEREG?命令
    try:
        serial_port.write(b'AT+CEREG?\r\n')
        time.sleep(1)
        response_lines = []
        while True:
            line = serial_port.readline().decode('utf-8').strip()
            response_lines.append(line)

            if line == 'OK':
                break

        # 检查是否有+CEREG响应
        for line in response_lines:
            pattern = r'\+CEREG:\s*\d,\s*(\d)'
            match = re.search(pattern, line)
            if match:
                cereg_value = int(match.group(1))
                return cereg_value

        # 如果没有找到+CEREG响应，则返回None
        return None
    except Exception as e:
        # print(f"get_cereg_value: {e}")
        logger.info(f"get_cereg_value: {e}")
def get_cfun_value(serial_port):
    try:
        # 发送AT+CFUN?命令
        serial_port.write(b'AT+CFUN?\r\n')
        time.sleep(1)
        response_lines = []
        while True:
            line = serial_port.readline().decode('utf-8').strip()
            response_lines.append(line)

            if line == 'OK':
                break


        # 检查是否有+CEREG响应
        for line in response_lines:
            pattern = r'\+CFUN:\s*(\d)'
            match = re.search(pattern, line)
            if match:
                cfun_value = int(match.group(1))
                return cfun_value

        # 如果没有找到+CFUN的响应，则返回None
        return None
        # 解析+CFUN值
    except Exception as e:
        # print(f"get_cfun_value: {e}")
        logger.info(f"get_cfun_value: {e}")


def save_to_excel(rsrp, connection_status, excel_file):
    # excel_file = 'data_240118.xlsx'
    sheet_name = 'Data'
    global reboot_timer_start_now
    global reboot_timer_start

    try:
        if os.path.isfile(excel_file):
            # 读取已存在的Excel文件
            df = pd.read_excel(excel_file, sheet_name=sheet_name)
        else:
            # 创建一个新的DataFrame，如果文件不存在
            df = pd.DataFrame(columns=['RSRP', 'Connection_Status', 'Start_Time', 'End_Time'])

        rs = time.strftime('%Y-%m-%d %H:%M', time.localtime(reboot_timer_start))
        rsn = time.strftime('%Y-%m-%d %H:%M', time.localtime(reboot_timer_start_now))
        # 使用concat添加新行
        new_row = {'RSRP': rsrp, 
                   'Connection_Status': connection_status,
                   'Start_Time': rs,
                  'End_Time': rsn
                   }
        df = pd.concat([df, pd.DataFrame(new_row, index=[0])], ignore_index=True)

        # 将数据写入Excel文件
        df.to_excel(excel_file, sheet_name=sheet_name, index=False)
    except Exception as e:
        # print(f"Error saving to Excel: {e}")
        logger.info(f"Error saving to Excel: {e}")



def send_AT_NRB_command(serial_port):

    try:
        # print("enter send_AT_NRB_command")
        logger.info("enter send_AT_NRB_command")
        # 发送AT+NRB指令
        serial_port.write(b'AT+NRB\r\n')
    except Exception as e:
        # print(f"send_AT_NRB_command: {e}")
        logger.info(f"send_AT_NRB_command: {e}")

def ParserFunc():
    # global ser 
    # 创建一个解析器对象
    parser = argparse.ArgumentParser(description='获取串口号参数')
    
    # 添加一个名为 com 的位置参数，表示串口号
    parser.add_argument('com', type=str, help='串口号')

    # 添加一个名为 --rst 的 可选 复位参数，表示启动执行复位
    parser.add_argument('--rst', action='store_true', help='表示启动执行复位')
    
    # 解析命令行参数
    args = parser.parse_args()

    return args
    
    # # 判断是否输入了串口号参数
    # if args.com.startswith('COM'):
    #     # 给 com 变量赋值
    #     com = args.com

    #     ser = serial.Serial(com, 9600, 8, "N", 1, 2)  # 替换为你的串口号和波特率
    
    #     # 打印 com 的值
    #     print('com =', com)
    # else:
    #     # 提示错误并结束程序
    #     print('错误：请输入合法的串口号参数')
    #     sys.exit(1)

def main(logger, ser, excel_file):
    rsrp = None
    connection_success = False
    timer_flag = False
    begin_flag = True

    while True:
        try:
            line = ser.readline().decode('utf-8').strip()
        except Exception as e:
            # print(f"[main] readline fail: {e}")
            logger.info(f"[main] readline fail: {e}")

        # 监听异常复位
        if line == 'REBOOT_CAUSE_PROTOCOL_SYSRESETREQ':
            # print("enter 3")
            logger.info("enter 3")
            connection_status = "Abnormal Reset"
            connection_success = True
            # print("write to excel beacuse SYSRESETREQ")
            logger.info("write to excel beacuse SYSRESETREQ")
            timer_flag = False
            begin_flag = True
            send_AT_NRB_command(ser)  # 调用send_AT_NRB_command并检查返回值

        while begin_flag:
            begin_flag = False
            # if line == 'REBOOT_CAUSE_SECURITY_PMU_POWER_ON_RESET' or line == 'REBOOT_CAUSE_APPLICATION_AT':
            # print("enter 1")
            logger.info("enter 1")
            # reboot_detected = True
            # while timer_flag:
            global reboot_timer_start
            reboot_timer_start = time.time()  # 记录重启计时器的开始时间
            while reboot_timer_start is None:
                time.sleep(1)
                break
            # print("Current time since epoch: %f" % reboot_timer_start)
            logger.info("Current time since epoch: %f" % reboot_timer_start)
            timer_flag = True
            # print("enter read_rsrp")
            logger.info("enter read_rsrp")
            rsrp = read_rsrp(ser)
            # print(f"RSRP Value: {rsrp}")
            logger.info(f"RSRP Value: {rsrp}")

        cereg_value = get_cereg_value(ser)
        # print(F"CEREG = {cereg_value}")
        logger.info(F"CEREG = {cereg_value}")
        if cereg_value == 1:
            # AT_CMD_TYPE = False
            # print("cereg_value = %d" % cereg_value.value)
            connection_success = True
            connection_status = "Success"
            # print("connect success, try to send AT+NRB")
            logger.info("connect success, try to send AT+NRB")
            timer_flag = False
            begin_flag = True
            send_AT_NRB_command(ser)  # 调用send_AT_NRB_command并检查返回值
            time.sleep(0.1)

        global reboot_timer_start_now
        reboot_timer_start_now = time.time()
        time.sleep(0.1)
        while reboot_timer_start_now is None:
                time.sleep(1)
                break

        if timer_flag:
            # timer_flag = False
            # 超过3分30秒未连接成功
            timer_cnt = reboot_timer_start_now - reboot_timer_start
            time.sleep(0.1)
            # print(f"time is {timer_cnt}")
            logger.info(f"time is {timer_cnt}")
            if timer_cnt > 210:
                connection_success = True
                connection_status = "time out"
                # print("connect fail, try to send AT+NRB")
                logger.info("connect fail, try to send AT+NRB")
                timer_flag = False
                begin_flag = True
                send_AT_NRB_command(ser)  # 调用send_AT_NRB_command并检查返回值
                # print("enter next while")
                logger.info("enter next while")
        
        if connection_success:
            connection_success = False
            # 当连接成功或重启事件处理完毕后，将RSRP和状态写入Excel
            if connection_status == "Success"  or connection_status == "time out" or connection_status == "Abnormal Reset":
                save_to_excel(rsrp, connection_status, excel_file)
                time.sleep(0.1)
                # reboot_detected = False
                reboot_timer_start = None  # 重置重启计时器

if __name__ == "__main__":
    try: 
        args = ParserFunc()

        # 判断是否输入了串口号参数
        if args.com.startswith('COM'):
            # 给 com 变量赋值
            com = args.com

            ser = serial.Serial(com, 9600, 8, "N", 1, 2)  # 替换为你的串口号和波特率
        
            # 打印 com 的值
            print('------com = %s -------' % com)
        else:
            # 提示错误并结束程序
            print('错误：请输入合法的串口号参数')
            sys.exit(1)
        
        # 获取当前的 com 名和日期
        date = time.strftime('%Y-%m-%d_%H-%M', time.localtime())
        print('------date = %s -------' % date)
        log_name = com + '_' + date + '.log'
        excel_file = com + '_' + date + '.xlsx'


        logger = MyLogging(name='skf_p', path='log/%s' % log_name , level= logging.DEBUG)
        logger.info("test time: %f" % reboot_timer_start)

        # --rst 处理
        if args.rst:
            logger.info("---rst detected---")
            send_AT_NRB_command(ser)
            time.sleep(3)
        logger.info("---main run---")
        main(logger, ser, excel_file)
    except:
        logger.error("---main error---")
    finally:
        logger.error("---finally ser.close---")
        ser.close()